/*
package com.scut.campus.aop;

import com.scut.campus.annotation.BusinessIdempotent;
import com.shopee.bcf.logging.logger.BcfLogger;
import com.shopee.bcf.logging.logger.BcfLoggerFactory;
import com.shopee.bizf.common.context.BizContextHolder;
import com.shopee.bizf.common.util.JsonUtil;
import com.shopee.bizf.norm.api.constant.ApiConstant;
import com.shopee.bizf.norm.err.common.SystemErrorCodeEnum;
import com.shopee.bizf.norm.exception.BaseException;
import com.shopee.bizf.norm.exception.BizfException;
import com.shopee.bizf.norm.exception.IdempotentException;

import com.shopee.bizf.service.idempotent.util.BusinessIdempotentUtil;
import com.shopee.bizf.service.idempotent.util.IdempotentUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

import java.lang.reflect.Method;

import static com.shopee.bizf.norm.err.common.BizErrorCodeEnum.IDEM_CLASS_NOT_FOUND;
import static com.shopee.bizf.norm.err.common.SystemErrorCodeEnum.IDEM_CLASS_CONFLICT;

*/
/**
 * business idempotent aspect, cannot be used in facade
 *
 * @author kai
 * @version BusinessIdempotentAspect.java v1.0 2022-05-13
 *//*


@Component
@Aspect
public class BusinessIdempotentAspect {

    */
/**
     * biz idem util
     *//*

    @Autowired
    private BusinessIdempotentUtil bizIdemUtil;

    */
/**
     * template
     *//*

    @Autowired
    @Qualifier("transactionTemplate")
    TransactionTemplate transactionTemplate;

    */
/**
     * point cut
     *//*

    @Pointcut("@annotation(com.scut.campus.annotation.BusinessIdempotent)")
    public void pointCut() {

    }

    */
/**
     * aop
     *
     * @param pjp pjp
     * @return object
     * @throws Throwable throw
     *//*

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Signature signature = pjp.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        HttpServletRequest request = ((ServletRequestAttributes)
            RequestContextHolder.getRequestAttributes()).getRequest();

        // 记录路径和JSON体
        String path = request.getRequestURI();
        String jsonBody = objectMapper.writeValueAsString(pjp.getArgs()[0]);

        BusinessIdempotent businessIdempotent = method.getAnnotation(BusinessIdempotent.class);
        if (businessIdempotent == null) {
            return pjp.proceed();
        }

        if (BizContextHolder.getBizContext() == null || StringUtils.isBlank(BizContextHolder.getBizContext().getReqBizNo())) {
            return pjp.proceed();
        }

        return transactionTemplate.execute(transactionStatus -> {
                    Class<?> returnType = methodSignature.getReturnType();

                    Object res;
                    try {
                        bizIdemUtil.processBizIdempotent(null, IdempotentUtil.getBizIdemServiceId(method));
                    } catch (IdempotentException exception) {
                        String originalResponse = exception.getOriginalResponse();
                        String originalResponseClass = exception.getOriginalResponseClass();
                        return getOriginalResultObject(returnType, originalResponse, originalResponseClass);
                    }

                    try {
                        res = pjp.proceed();
                        bizIdemUtil.updateBizIdempotent(null, ApiConstant.SUCCESS_CODE, res, returnType);
                    } catch (BaseException baseException) {
                        transactionStatus.setRollbackOnly();
                        throw baseException;
                    } catch (Throwable e) {
                        transactionStatus.setRollbackOnly();
                        LOGGER.error("unknown exception!", e);
                        throw new BizfException(SystemErrorCodeEnum.INNER_SYSTEM_ERROR);
                    }
                    return res;
                }
        );
    }

    */
/**
     * get original result
     *
     * @param returnType       return type
     * @param originalResponse response
     * @param originalClass    class
     * @return object
     *//*

    private Object getOriginalResultObject(Class<?> returnType, String originalResponse, String originalClass) {
        if (returnType.isPrimitive()) {
            if (!returnType.getName().equals(originalClass)) {
                LOGGER.error("biz idem class conflict, original response class:{}, current class: {}",
                        originalClass,
                        returnType.getName());
                throw new BizfException(IDEM_CLASS_CONFLICT);
            } else {
                if (Boolean.class == returnType || Boolean.TYPE == returnType) {
                    return Boolean.parseBoolean(originalResponse);
                }
                if (Byte.class == returnType || Byte.TYPE == returnType) { return Byte.parseByte(originalResponse); }
                if (Short.class == returnType || Short.TYPE == returnType) { return Short.parseShort(originalResponse); }
                if (Integer.class == returnType || Integer.TYPE == returnType) { return Integer.parseInt(originalResponse); }
                if (Long.class == returnType || Long.TYPE == returnType) { return Long.parseLong(originalResponse); }
                if (Float.class == returnType || Float.TYPE == returnType) { return Float.parseFloat(originalResponse); }
                if (Double.class == returnType || Double.TYPE == returnType) { return Double.parseDouble(originalResponse); }
                // void type return null
                return null;
            }
        }

        // return null if original response is empty
        if (StringUtils.isBlank(originalResponse)) {
            return null;
        }

        Class<?> originalReturnType;
        try {
            originalReturnType = Class.forName(originalClass);
        } catch (ClassNotFoundException e) {
            throw new BizfException(IDEM_CLASS_NOT_FOUND);
        }
        if (!returnType.isAssignableFrom(originalReturnType)) {
            LOGGER.error("biz idem class conflict, original response class:{}, current class: {}",
                    originalReturnType.getName(),
                    returnType.getName());
            throw new BizfException(IDEM_CLASS_CONFLICT);
        }
        return JsonUtil.parseObject(originalResponse, originalReturnType);
    }
}
 
 
*/
